using System;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.WebPages;

namespace MvcApplication1.Models
{
    public class IdGenerator
    {
        private static int id;
        public static string New()
        {
            return "id" + id++;
        }
    }

    public class HtmlFragment
    {
        public readonly string DivId;
        public readonly string Html;

        public HtmlFragment(string divId, string html)
        {
            DivId = divId;
            Html = html;
        }

        public HtmlFragment(string divId, HelperResult helperResult)
            : this(divId, helperResult.ToString())
        {
        }
    }

    public class HtmlHelperContext
    {
        public readonly RequestContext RequestContext;

        public HtmlHelperContext(RequestContext requestContext)
        {
            RequestContext = requestContext;
        }

        public static implicit operator HtmlHelperContext(ControllerBase it)
        {
            return new HtmlHelperContext(it.ControllerContext.RequestContext);
        }

        public static implicit operator HtmlHelperContext(WebViewPage it)
        {
            return new HtmlHelperContext(it.ViewContext.RequestContext);
        }
    }

    public static class Util
    {
        public static bool IsAjax
        {
            get { return true; }
        }

        public static ActionResult As(this HelperResult it, Func<string, object, ViewResult> func)
        {
            return func("~/Views/View1.cshtml", it);
        }

        public static string By<T>(this HtmlHelperContext it, Expression<Func<T, Func<ActionResult>>> expression)
        {
            var methodInfo = (MethodInfo) ((dynamic) expression).Body.Operand.Object.Value;
            var typeName = methodInfo.DeclaringType.Name;
            return (IsAjax ? "#" : "") + UrlHelper.GenerateContentUrl(
                "~/" + typeName.Substring(0, typeName.Length - "Controller".Length)
                + "/" + methodInfo.Name, it.RequestContext.HttpContext);
        }

        public static T ToEnum<T>(this string it)
        {
            return (T) Enum.Parse(typeof (T), it);
        }

        public static string RenderPartialViewToString(Controller it, string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = it.ControllerContext.RouteData.GetRequiredString("action");

            it.ViewData.Model = model;

            var stringBuilder = new StringBuilder();
            using (var writer = new StringWriter(stringBuilder))
            {
                var viewEngineResult = ViewEngines.Engines.FindPartialView(it.ControllerContext, viewName);
                viewEngineResult.View.Render(
                    new ViewContext(
                        it.ControllerContext,
                        viewEngineResult.View,
                        it.ViewData,
                        it.TempData,
                        writer),
                    writer);
            }
            return stringBuilder.ToString();
        }

    }
}